package com.ruoyi.scale.rule.impl;

import com.ruoyi.scale.assembler.GrowthInputAssembler;
import com.ruoyi.scale.document.Scale;
import com.ruoyi.scale.document.ScaleLog;
import com.ruoyi.scale.document.refs.ScaleResult;
import com.ruoyi.scale.model.GrowthInput;
import com.ruoyi.scale.model.GrowthNormData;
import com.ruoyi.scale.model.GrowthNormDataWrap;
import com.ruoyi.scale.model.GrowthOutput;
import com.ruoyi.scale.rule.EvalRule;
import com.ruoyi.scale.utils.MathUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Component("growthEvalRule")
public class GrowthEvalRule implements EvalRule {
    @Resource
    private GrowthInputAssembler growthInputAssembler;
    @Override
    public void prepare(ScaleLog scaleLog) {
        Assert.notNull(scaleLog.getMonthAge(),"月龄不能为空!");
        Assert.notNull(scaleLog.getSex(),"性别不能为空!");
        Assert.isTrue(scaleLog.getSex() == 1 || scaleLog.getSex() == 2 , "性别非法值！");
        Assert.notNull(scaleLog.getFormData(),"输入表单不能为空!");
    }

    /**
     * 是否7岁以下
     * @param monthAge
     * @return
     */
    public boolean is7YearYoung(Integer monthAge){
        return monthAge <= 84;
    }


    @Override
    public ScaleResult eval(Scale scale, ScaleLog scaleLog) {
        GrowthInput growthInput = (GrowthInput)scaleLog.getFormData();
        GrowthNormDataWrap growthNormDataWrap = (GrowthNormDataWrap)scale.getNormData();
        GrowthOutput growthOutput = growthInputAssembler.buildGrowthOutput(growthInput);
        //体重
        assemblerWeight(scaleLog.getMonthAge(),scaleLog.getSex(),growthNormDataWrap,growthInput,growthOutput);
        //身高
        assemblerHeight(scaleLog.getMonthAge(),scaleLog.getSex(),growthNormDataWrap,growthInput,growthOutput);
        //bmi
        assemblerBmi(scaleLog.getMonthAge(),scaleLog.getSex(),growthNormDataWrap,growthInput,growthOutput);
        //身体体长
        assemblerHeightWeight(scaleLog.getMonthAge(),scaleLog.getSex(),growthNormDataWrap,growthInput,growthOutput);
        //头围
        assemblerTw(scaleLog.getMonthAge(),scaleLog.getSex(),growthNormDataWrap,growthInput,growthOutput);
        //胸围
        assemblerXw(scaleLog.getMonthAge(),scaleLog.getSex(),growthNormDataWrap,growthInput,growthOutput);

        scaleLog.setExtResult(growthOutput);
        return null;
    }

    /**
     * 组装体重
     * @param monthAge
     * @param sex
     * @param growthNormDataWrap
     * @param growthInput
     * @param growthOutput
     */
    private void assemblerWeight(double monthAge,
                                 Integer sex,
                                 GrowthNormDataWrap growthNormDataWrap,
                                 GrowthInput growthInput,
                                 GrowthOutput growthOutput) {
        //标准差评价方法
        List<GrowthNormData> normSdDataList = growthNormDataWrap.ageWeightSd7(sex);
        GrowthNormData growthSdNormData = growthNormDataWrap.matchNorm(monthAge,normSdDataList);
        //百分位数评价方法
        List<GrowthNormData> normPerDataList = growthNormDataWrap.ageWeightPer7(sex);
        GrowthNormData growthPerNormData = growthNormDataWrap.matchNorm(monthAge,normPerDataList);

        growthOutput.assemblerWeight(monthAge,growthInput.getWeight(),growthSdNormData,normSdDataList, growthPerNormData,normPerDataList);
    }

    /**
     * 组装身高
     * @param monthAge
     * @param sex
     * @param growthNormDataWrap
     * @param growthInput
     * @param growthOutput
     */
    private void assemblerHeight(double monthAge,
                                 Integer sex,
                                 GrowthNormDataWrap growthNormDataWrap,
                                 GrowthInput growthInput,
                                 GrowthOutput growthOutput) {
        //标准差评价方法
        List<GrowthNormData> normSdDataList = growthNormDataWrap.ageAgeHeightSd7(sex);
        GrowthNormData growthSdNormData = growthNormDataWrap.matchNorm(monthAge,normSdDataList);
        //百分位数评价方法
        List<GrowthNormData> normPerDataList = growthNormDataWrap.ageHeightPer7(sex);
        GrowthNormData growthPerNormData = growthNormDataWrap.matchNorm(monthAge,normPerDataList);

        growthOutput.assemblerHeight(monthAge,growthInput.getHeight(),growthSdNormData,normSdDataList, growthPerNormData,normPerDataList);
    }

    /**
     * bmi
     * @param monthAge
     * @param sex
     * @param growthNormDataWrap
     * @param growthInput
     * @param growthOutput
     */
    private void assemblerBmi(double monthAge,
                                 Integer sex,
                                 GrowthNormDataWrap growthNormDataWrap,
                                 GrowthInput growthInput,
                                 GrowthOutput growthOutput) {


        //标准差评价方法
        List<GrowthNormData> normSdDataList = growthNormDataWrap.ageBmiSd7(sex);
        GrowthNormData growthSdNormData = growthNormDataWrap.matchNorm(monthAge,normSdDataList);
        //百分位数评价方法
        List<GrowthNormData> normPerDataList = growthNormDataWrap.ageBmiPer7(sex);
        GrowthNormData growthPerNormData = growthNormDataWrap.matchNorm(monthAge,normPerDataList);

        BigDecimal bim = MathUtil.bim(growthInput.getWeight(), growthInput.getHeight());
        growthOutput.assemblerBmi(monthAge,bim.doubleValue(), growthSdNormData,normSdDataList,growthPerNormData,normPerDataList);
    }

    /**
     * 头围
     * @param monthAge
     * @param sex
     * @param growthNormDataWrap
     * @param growthInput
     * @param growthOutput
     */
    private void assemblerTw(double monthAge,
                                 Integer sex,
                                 GrowthNormDataWrap growthNormDataWrap,
                                 GrowthInput growthInput,
                                 GrowthOutput growthOutput) {
        if(monthAge > 36){
            return;
        }

        //标准差评价方法
        List<GrowthNormData> normSdDataList = growthNormDataWrap.ageTwSd0_3(sex);
        GrowthNormData growthSdNormData = growthNormDataWrap.matchNorm(monthAge,normSdDataList);
        //百分位数评价方法
        List<GrowthNormData> normPerDataList = growthNormDataWrap.ageTwPer0_3(sex);
        GrowthNormData growthPerNormData = growthNormDataWrap.matchNorm(monthAge,normPerDataList);

        growthOutput.assemblerTw(monthAge,growthInput.getHeight(), growthSdNormData,growthPerNormData);
    }

    /**
     * 组装身长
     * @param monthAge
     * @param sex
     * @param growthNormDataWrap
     * @param growthInput
     * @param growthOutput
     */
    private void assemblerHeightWeight(double monthAge, Integer sex, GrowthNormDataWrap growthNormDataWrap, GrowthInput growthInput, GrowthOutput growthOutput) {
        //标准差评价方法
        List<GrowthNormData> normSdDataList = null;
        //百分位数评价方法
        List<GrowthNormData> normPerDataList = null;
        if(monthAge < 24){
            normSdDataList = growthNormDataWrap.heightWeightSd0_2(sex);
            normPerDataList = growthNormDataWrap.heightWeightPer0_2(sex);
        } else {
            normSdDataList = growthNormDataWrap.heightWeightSd2_7(sex);
            normPerDataList = growthNormDataWrap.heightWeightPer2_7(sex);
        }
        //标准差评价方法
        GrowthNormData growthSdNormData = growthNormDataWrap.matchNorm(growthInput.getHeight(),normSdDataList);
        GrowthNormData growthPerNormData = growthNormDataWrap.matchNorm(growthInput.getHeight(),normPerDataList);

        growthOutput.assemblerHeightWeight(monthAge,growthInput.getWeight(), growthSdNormData,normSdDataList,growthPerNormData,normPerDataList);
//        List<GrowthNormData> bodyLengthNormData = growthNormDataWrap.getBodyLength(sex);
//        GrowthNormData growthNormData = growthNormDataWrap.matchNorm(growthInput.getHeight(),bodyLengthNormData);
//        growthOutput.assemblerBodyLength(monthAge,growthInput.getHeight(), growthNormData,bodyLengthNormData);
    }

    /**
     * 胸围
     * @param monthAge
     * @param sex
     * @param growthNormDataWrap
     * @param growthInput
     * @param growthOutput
     */
    private void assemblerXw(double monthAge,
                                 Integer sex,
                                 GrowthNormDataWrap growthNormDataWrap,
                                 GrowthInput growthInput,
                                 GrowthOutput growthOutput) {

    }

}
